﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Noris.Tools.TraceVisualiser.Components;

namespace Noris.Tools.TraceVisualiser.Forms
{
    [DefaultEvent("FindText")]
    internal class FindTextPanel : DPanel
    {
        public FindTextPanel()
        {
            this.InitializeComponent();
            this._InitData();
        }
        private void _InitData()
        {
            this._NextBut.Image = Pics.PicLibrary16.GoDown3_FromFile;
            this._PrevBut.Image = Pics.PicLibrary16.GoUp3_FromFile;
        }
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.Size = new System.Drawing.Size(440, 25);

            this._FindLabel = new System.Windows.Forms.Label();
            this._FindText = new System.Windows.Forms.TextBox();
            this._NextBut = new System.Windows.Forms.Button();
            this._PrevBut = new System.Windows.Forms.Button();
            
            // _FindLabel
            this._FindLabel.Anchor = (AnchorStyles)(AnchorStyles.Left | AnchorStyles.Top);
            this._FindLabel.AutoSize = true;
            this._FindLabel.Location = new System.Drawing.Point(4, 6);
            this._FindLabel.Name = "_FindLabel";
            this._FindLabel.Size = new System.Drawing.Size(30, 13);
            this._FindLabel.TabIndex = 1;
            this._FindLabel.Text = "Find:";
            
            // _FindText
            this._FindText.Anchor = (AnchorStyles)(AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right);
            this._FindText.Location = new System.Drawing.Point(40, 3);
            this._FindText.Name = "_FindText";
            this._FindText.Size = new System.Drawing.Size(345, 20);
            this._FindText.TabIndex = 2;
            this._FindText.Enter += new EventHandler(_FindText_Enter);
            this._FindText.Leave += new EventHandler(_FindText_Leave);

            
            // _NextBut
            this._NextBut.Anchor = (AnchorStyles)(AnchorStyles.Top | AnchorStyles.Right);
            this._NextBut.Location = new System.Drawing.Point(386, 1);
            this._NextBut.Name = "_NextBut";
            this._NextBut.Size = new System.Drawing.Size(26, 23);
            this._NextBut.TabStop = false;
            this._NextBut.TabIndex = 3;
            this._NextBut.UseVisualStyleBackColor = true;
            this._NextBut.Click += new System.EventHandler(this._NextBut_Click);
            
            // _PrevBut
            this._PrevBut.Anchor = (AnchorStyles)(AnchorStyles.Top | AnchorStyles.Right);
            this._PrevBut.Location = new System.Drawing.Point(412, 1);
            this._PrevBut.Name = "_PrevBut";
            this._PrevBut.Size = new System.Drawing.Size(26, 23);
            this._PrevBut.TabStop = false;
            this._PrevBut.TabIndex = 4;
            this._PrevBut.UseVisualStyleBackColor = true;
            this._PrevBut.Click += new System.EventHandler(this._PrevBut_Click);

            // this
            this.Controls.Add(this._FindText);
            this.Controls.Add(this._FindLabel);
            this.Controls.Add(this._PrevBut);
            this.Controls.Add(this._NextBut);
            this.Location = new System.Drawing.Point(8, 7);
            this.Name = "panel1";
            this.TabIndex = 6;
            this.GotFocus += new EventHandler(FindTextPanel_GotFocus);
            this.Enter += new EventHandler(FindTextPanel_Enter);
            this.Leave += new EventHandler(FindTextPanel_Leave);

        }
        private System.Windows.Forms.Label _FindLabel;
        private System.Windows.Forms.TextBox _FindText;
        private System.Windows.Forms.Button _NextBut;
        private System.Windows.Forms.Button _PrevBut;
        #endregion
        #region Vnitřní události, změna textu, buttony
        /// <summary>
        /// Event volaný za účelem vyhledání textu.
		/// Tento event bude vyvolán po zadání nového textu a Enter, nebo po kliknutí na buttony Next/Prev.
        /// </summary>
        [Description("Event volaný za účelem vyhledání textu")]
        [Category("Data")]
        public event FindTextEventHandler FindText;
		/// <summary>
		/// Event volaný za účelem předání focusu do defaultního cíle.
		/// Tento event bude vyvolán po zadání nového textu a Enter, nebo po kliknutí na buttony Next/Prev, po doběhnutí eventu FindText.
		/// </summary>
		[Description("Event volaný za účelem předání focusu do defaultního cíle.")]
		[Category("Data")]
		public event EventHandler FocusToText;
		/// <summary>
		/// Invoker eventu FindText
		/// </summary>
		/// <param name="text"></param>
		/// <param name="mode"></param>
        protected void OnFindText(string text, FindTextMode mode)
        {
            if (this.FindText != null)
                this.FindText(this, new FindTextEventArgs(text, mode));
        }
		/// <summary>
		/// Invoker eventu FocusToText
		/// </summary>
        protected void OnFocusToText()
        {
			if (this.FocusToText != null)
				this.FocusToText(this, EventArgs.Empty);
        }
        /// <summary>
        /// Vstup do panelu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void FindTextPanel_GotFocus(object sender, EventArgs e)
        {
        }
        /// <summary>
        /// Vstup do panelu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void FindTextPanel_Enter(object sender, EventArgs e)
        {
            this._CurrentFindText = this._FindText.Text;
            Form form = this.FindForm();
            if (form != null)
            {
                if (!Object.ReferenceEquals(form.AcceptButton, this._NextBut))   // Pokud formulář má jiný Accept button než je náš NextButton, pak si zapamatujeme ten formulářový:
                    this._FormAcceptButton = form.AcceptButton;
                form.AcceptButton = this._NextBut;
            }
        }
        /// <summary>
        /// Vstup do textboxu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _FindText_Enter(object sender, EventArgs e)
        {
            this._PreEditText = this._FindText.Text;
        }
        /// <summary>
        /// Odchod z textboxu (může být odchod na button Next/Prev, anebo úplně jinam).
        /// Pokud odcházím do buttonů, tak nereaguji. Pokud odcházím z panelu, řeší to event handler this.FindTextPanel_Leave()
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _FindText_Leave(object sender, EventArgs e)
        {
            
        }
        /// <summary>
        /// Odchod z panelu
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void FindTextPanel_Leave(object sender, EventArgs e)
        {
            this._FindText.Text = this._CurrentFindText;

            Form form = this.FindForm();
            if (form != null)
            {
                if (Object.ReferenceEquals(this._FormAcceptButton, this._NextBut))
                    form.AcceptButton = null;
                else
                    form.AcceptButton = this._FormAcceptButton;
            }
        }
        /// <summary>
        /// Button Next = Accept
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _NextBut_Click(object sender, EventArgs e)
        {
            string text = this._FindText.Text;
            bool change = (text != this._PreEditText);
            this._PreEditText = text;
            this._CurrentFindText = text;
            if (change)
                this.OnFindText(text, FindTextMode.FindFirst);
            else
                this.OnFindText(text, FindTextMode.FindNext);

			this.OnFocusToText();
        }
        /// <summary>
        /// Button Prev
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _PrevBut_Click(object sender, EventArgs e)
        {
            string text = this._FindText.Text;
            bool change = (text != this._PreEditText);
            this._PreEditText = text;
            this._CurrentFindText = text;
            if (change)
                this.OnFindText(text, FindTextMode.FindLast);
            else
                this.OnFindText(text, FindTextMode.FindPrev);

			this.OnFocusToText();
		}
        private string _PreEditText;
        private string _CurrentFindText;
        private IButtonControl _FormAcceptButton;

        #endregion
    }
    #region delegate, EventArgs, enum FindTextMode
    /// <summary>
    /// Delegát pro metodu, která řeší Find (text, mode)
    /// </summary>
    /// <param name="sender">Odesilatel eventu</param>
    /// <param name="args">Data eventu</param>
    internal delegate void FindTextEventHandler(object sender, FindTextEventArgs args);
    internal class FindTextEventArgs : EventArgs
    {
        public FindTextEventArgs(string findText, FindTextMode findMode)
        {
            this.FindText = findText;
            this.FindMode = findMode;
        }
        public string FindText { get; private set; }
        public FindTextMode FindMode { get; private set; }
    }
    public enum FindTextMode
    {
        None = 0,
        FindFirst,
        FindNext,
        FindPrev,
        FindLast
    }
    #endregion
}
